﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
using System.Globalization;
using System.Web;
using System.Web.Mvc;
using Microsoft.Web;
using OpenQuarters.WebQuarters.Utils;
using System.Web.UI.WebControls;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Xml.Serialization;

namespace OpenQuarters.WebQuarters.Core.Web.Areas.CMS.Controllers
{
    public class FileController : Controller
    {
        public ActionResult Image(string id)
        {
            string[] idArray = id.Split('/');
            string width = "";
            string height = "";
            string virtualPath = "";
            string path;
            string extension = null;
            System.Drawing.Imaging.ImageFormat contentType = null;

            if (idArray.Length > 2)
            {
                width = idArray[0];
                height = idArray[1];
                virtualPath = id.Substring(string.Format("{0}/{1}", idArray[0], idArray[1]).Length);
            }
            else
            {
                Oracle.Response.StatusCode = 404;
                Oracle.Response.End();
            }

            path = Server.MapPath("~/Areas/CMS/Content/UserFiles" + virtualPath);
            extension = Path.GetExtension(path).ToLower();

            // Prevent cross site image requests
            if (HttpContext.Request.UrlReferrer != null && Oracle.Request.UrlReferrer.Host.Length > 0)
            {
                if (
                CultureInfo.InvariantCulture.CompareInfo.Compare(Oracle.Request.Url.Host,
                    Oracle.Request.UrlReferrer.Host, CompareOptions.IgnoreCase) != 0)
                {
                    path = Oracle.Request.MapPath("~/Areas/CMS/Content/images/image_crosssiterequest.gif");
                    Oracle.Response.StatusDescription = "Image not found";
                    Oracle.Response.ContentType = System.Drawing.Imaging.ImageFormat.Gif.ToString();
                    Oracle.Response.StatusCode = 404;
                    Oracle.Response.WriteFile(path);
                    Oracle.Response.End();
                }
            }

            switch (extension)
            {
                case ".bmp":
                    contentType = System.Drawing.Imaging.ImageFormat.Bmp;
                    break;
                case ".gif":
                    contentType = System.Drawing.Imaging.ImageFormat.Gif;
                    break;
                case ".jpg":
                case ".jpeg":
                    contentType = System.Drawing.Imaging.ImageFormat.Jpeg;
                    break;
                case ".png":
                    contentType = System.Drawing.Imaging.ImageFormat.Png;
                    break;
                default:
                    throw new NotSupportedException("Unsupported image type.");
            }

            if (!System.IO.File.Exists(path))
            {
                path = Oracle.Request.MapPath("~/Areas/CMS/Content/images/image_imagenotfound.gif");
                Oracle.Response.StatusDescription = "Image not found";
                Oracle.Response.ContentType = System.Drawing.Imaging.ImageFormat.Gif.ToString();
                Oracle.Response.StatusCode = 404;
                Oracle.Response.WriteFile(path);
                Oracle.Response.End();
            }
            else
            {

                ImageInfo test;
                CustomImageHander imageHandler = new CustomImageHander(path, width, height, contentType);
                //handler.EnableClientCache = true;
                test = imageHandler.GenerateImage(null);
                imageHandler.Process();
                return File(test.ImageByteBuffer, contentType.ToString(), Path.GetFileName(path));
            }

            return View();
        }

        public ImageResult ImageTitle()
        {
            if (!string.IsNullOrEmpty(Oracle.Request.QueryString["opts"]))
            {

                XmlSerializer Serializer = new XmlSerializer(typeof(Core.ImageTitle));
                Core.ImageTitle imageTitle = (Core.ImageTitle)Serializer.Deserialize(new StringReader(Utils.Encryption.RijndaelSimple.Decrypt(Request.QueryString["opts"].Replace(" ", "+"))));

                string path;

                // Prevent cross site image requests
                if (HttpContext.Request.UrlReferrer != null && Oracle.Request.UrlReferrer.Host.Length > 0)
                {
                    if (
                    CultureInfo.InvariantCulture.CompareInfo.Compare(Oracle.Request.Url.Host,
                        Oracle.Request.UrlReferrer.Host, CompareOptions.IgnoreCase) != 0)
                    {
                        path = Oracle.Request.MapPath("~/Areas/CMS/Content/images/image_crosssiterequest.gif");
                        Oracle.Response.StatusDescription = "Image not found";
                        Oracle.Response.ContentType = System.Drawing.Imaging.ImageFormat.Gif.ToString();
                        Oracle.Response.StatusCode = 404;
                        Oracle.Response.WriteFile(path);
                        Oracle.Response.End();
                    }
                }

                ImageInfo test;
                Font font;
                Unit fontSize = Unit.Pixel(imageTitle.FontSize);


                FontStyle fontStyle = FontStyle.Regular;
                if (imageTitle.Bold)
                    fontStyle = fontStyle | FontStyle.Bold;
                if (imageTitle.Italic)
                    fontStyle = fontStyle | FontStyle.Italic;

                if (!string.IsNullOrEmpty(imageTitle.Font))
                {
                    try
                    {
                        PrivateFontCollection privateFontCollection = new PrivateFontCollection();
                        privateFontCollection.AddFontFile(Server.MapPath(imageTitle.Font));

                        font = new Font(privateFontCollection.Families[0], (float)fontSize.Value, fontStyle, GraphicsUnit.Pixel);
                    }
                    catch { font = new Font(FontFamily.GenericSansSerif, imageTitle.FontSize); }
                }
                else
                    font = new Font(FontFamily.GenericSansSerif, imageTitle.FontSize);

                SizeF layoutSize = new SizeF(1000, 1000);
                Bitmap bit = new Bitmap(imageTitle.Width == 0 ? 1 : imageTitle.Width, imageTitle.Height == 0 ? 1 : imageTitle.Height);
                SizeF stringSize = Graphics.FromImage(bit).MeasureString(imageTitle.title, font, layoutSize);

                StringFormat sf = new StringFormat(StringFormat.GenericTypographic);
                switch (imageTitle.TextDirection)
                {
                    case ImageTitleDirection.Vertical:
                        sf.FormatFlags = StringFormatFlags.DirectionVertical;
                        break;
                    case ImageTitleDirection.RightToLeft:
                        sf.FormatFlags = StringFormatFlags.DirectionRightToLeft;
                        break;
                }

                // Automatically size if not defined
                if (imageTitle.Width == 0 || imageTitle.Height == 0)
                {
                    bit.Dispose();
                    if (sf.FormatFlags == StringFormatFlags.DirectionVertical)
                        bit = new Bitmap((int)Math.Ceiling(stringSize.Height), (int)Math.Ceiling(stringSize.Width));
                    else
                        bit = new Bitmap((int)Math.Ceiling(stringSize.Width), (int)Math.Ceiling(stringSize.Height));
                }

                Graphics gra = Graphics.FromImage(bit);
                gra.Clear(ColorTranslator.FromHtml(imageTitle.BackColour));
                gra.SmoothingMode = SmoothingMode.HighQuality;
                gra.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
                //gra.TextContrast = 2;

                RectangleF rect;
                if (sf.FormatFlags == StringFormatFlags.DirectionVertical)
                    rect = new RectangleF(0, 0, (int)stringSize.Height, (int)stringSize.Width);
                else
                    rect = new RectangleF(0, 0, (int)stringSize.Width, (int)stringSize.Height);

                gra.DrawString(imageTitle.title, font, new SolidBrush(ColorTranslator.FromHtml(imageTitle.ForeColour)), rect, sf);
                gra.Flush();

                ImageInfo generatedImage = new CustomTitleImageHander(bit).GenerateImage(null);
                //bit.Save("d:\\temp\\test.gif");
                //return File(generatedImage.ImageByteBuffer, contentType.ToString(), "ImageTitle.gif");
                ImageResult result = new ImageResult();
                result.Image = generatedImage.Image;
                result.ImageFormat = (System.Drawing.Imaging.ImageFormat)new System.Drawing.ImageFormatConverter().ConvertFromString(imageTitle.Format);
                return result;
            }
            else
                throw new ApplicationException("You must pass the options for query string");
        }

        public ActionResult Resource(string assembly, string filename)
        {
            Oracle.Response.Cache.SetCacheability(HttpCacheability.Public);

            try
            {
                var fileStream = Utils.Resource.GetEmbeddedFile(assembly, filename);
                var eTag = new StreamReader(fileStream).ReadToEnd().MD5Encrypt();

                Oracle.Response.AppendHeader("Content-Length", fileStream.Length.ToString());
                Oracle.Response.Cache.SetETag(eTag);

                if (Oracle.Request.Headers["If-None-Match"] != null && Oracle.Request.Headers["If-None-Match"] == eTag)
                {
                    Oracle.Response.ClearContent();
                    Oracle.Response.StatusCode = 304;
                    Oracle.Response.StatusDescription = "Not Modified";
                    Oracle.Response.End();
                }

                return File(Utils.Resource.GetEmbeddedFile(assembly, filename), Utils.Resource.GetMimeType(filename));
            }
            catch (FileNotFoundException)
            {
                HttpContext.Response.StatusDescription = "Image not found";
                Oracle.Response.StatusCode = 404;
                Oracle.Response.ContentType = System.Drawing.Imaging.ImageFormat.Gif.ToString();
                Oracle.Response.WriteFile(Oracle.Request.MapPath("~/Areas/CMS/Content/images/image_resourcenotfound.gif"));
                Oracle.Response.End();
            }
            catch (IOException)
            {
                HttpContext.Response.StatusDescription = "Image not found";
                Oracle.Response.StatusCode = 404;
                Oracle.Response.ContentType = System.Drawing.Imaging.ImageFormat.Gif.ToString();
                Oracle.Response.WriteFile(Oracle.Request.MapPath("~/Areas/CMS/Content/images/image_resourcenotfound.gif"));
                Oracle.Response.End();
            }

            return View();
        }

        #region JavaScripts

        public ActionResult CommonScripts()
        {
            Oracle.Response.AppendHeader("Content-Type", "text/javascript");
            Resources.OutputResources(Core.JavaScript.CommonScripts, Core.JavaScript.CommonScripts.ETag);
            Oracle.Response.End();

            return View();
        }

        public ActionResult PageScripts()
        {
            Oracle.Response.AppendHeader("Content-Type", "text/javascript");
            Resources.OutputResources(Core.JavaScript.PageScripts);
            Oracle.Response.End();

            return View();
        }

        public ActionResult StartupScripts()
        {
            Oracle.Response.AppendHeader("Content-Type", "text/javascript");
            Oracle.Response.Write("$().ready(function() {" + System.Environment.NewLine);
            Resources.OutputResources(Core.JavaScript.StartupScripts);
            Resources.OutputResources(Core.JavaScript.ModuleStartupScripts);
            Oracle.Response.Write(System.Environment.NewLine + "});");
            Oracle.Response.End();

            return View();
        }


        public ActionResult ModuleStartupScripts()
        {
            Oracle.Response.AppendHeader("Content-Type", "text/javascript");
            Resources.OutputResources(Core.JavaScript.ModuleStartupScripts);
            Oracle.Response.End();

            return View();
        }

        public ActionResult AdminScripts()
        {
            Oracle.Response.AppendHeader("Content-Type", "text/javascript");
            Resources.OutputResources(Core.JavaScript.AdminScripts);
            Oracle.Response.End();

            return View();
        }

        public ActionResult AdminStartupScripts()
        {
            Oracle.Response.AppendHeader("Content-Type", "text/javascript");
            Oracle.Response.Write("$().ready(function() {" + System.Environment.NewLine);
            Resources.OutputResources(Core.JavaScript.AdminStartupScripts);
            Oracle.Response.Write(System.Environment.NewLine + "});");
            Oracle.Response.End();

            return View();
        }

        #endregion

        #region CSS

        public ActionResult PageStyleSheets()
        {
            Oracle.Response.AppendHeader("Content-Type", "text/css");
            Resources.OutputResources(Core.CSS.PageStyleSheets);
            Oracle.Response.End();

            return View();
        }

        public ActionResult AdminStyleSheets()
        {
            Oracle.Response.AppendHeader("Content-Type", "text/css");
            Resources.OutputResources(Core.CSS.AdminStyleSheets);
            Oracle.Response.End();

            return View();
        }

        #endregion
    }

    public class CustomImageHander : ImageHandler
    {
        string path = "";
        string width = "0";
        string height = "0";

        public CustomImageHander(string path, string width, string height, System.Drawing.Imaging.ImageFormat contentType)
        {
            this.path = path;
            this.width = width;
            this.height = height;
            this.ContentType = contentType;
        }

        public override ImageInfo GenerateImage(System.Collections.Specialized.NameValueCollection parameters)
        {
            ImageResizeTransform resize = new ImageResizeTransform();
            if (width.Length != 0)
                resize.Width = Convert.ToInt32(width);
            if (height.Length != 0)
                resize.Height = Convert.ToInt32(height);
            resize.Mode = ImageResizeMode.Fit;
            //this.ImageTransforms.Add(resize);

            Bitmap test = new Bitmap(path);
            ImageInfo image = new ImageInfo(resize.ProcessImage(test));
            return image;
        }

        public void Process()
        {
            this.ProcessRequest(HttpContext.Current);
        }
    }

    public class CustomTitleImageHander : ImageHandler
    {
        Bitmap bitmap = null;

        public CustomTitleImageHander(Bitmap bitmap)
        {
            this.bitmap = bitmap;
        }

        public override ImageInfo GenerateImage(System.Collections.Specialized.NameValueCollection parameters)
        {
            ImageInfo image = new ImageInfo(this.bitmap);
            return image;
        }

        public void Process()
        {
            this.ProcessRequest(HttpContext.Current);
        }
    }
}
